package database

import (
	"context"
	"database/sql"

	"changeme/internal/models"
)

// DatabaseDriver 数据库驱动接口
type DatabaseDriver interface {
	// 连接管理
	Connect(config *models.DatabaseConfig) error
	Disconnect() error
	Ping() error
	IsConnected() bool
	GetVersion() (string, error)

	// 数据库操作
	ListDatabases(ctx context.Context) ([]models.DatabaseInfo, error)
	ListTables(ctx context.Context, database string) ([]models.TableInfo, error)
	GetTableColumns(ctx context.Context, database, table string) ([]models.ColumnInfo, error)
	GetTableIndexes(ctx context.Context, database, table string) ([]models.IndexInfo, error)

	// SQL执行
	ExecuteQuery(ctx context.Context, query string, args ...interface{}) (*models.QueryResult, error)
	ExecuteNonQuery(ctx context.Context, query string, args ...interface{}) (int64, error)

	// 事务支持
	BeginTransaction(ctx context.Context) (DatabaseTransaction, error)

	// 获取原始连接（用于高级操作）
	GetRawConnection() interface{}

	// 获取数据库能力
	GetCapabilities() DatabaseCapabilities

	// 表设计相关
	GenerateCreateTableSQL(database string, tableSchema *models.TableSchema) (string, error)
	GenerateAlterTableSQL(database, table string, alterSchema *models.TableAlterSchema) ([]string, error)
	GenerateDropTableSQL(database, table string, cascade bool) string
	GenerateRenameTableSQL(database, oldTable, newTable string) string
	GenerateTruncateTableSQL(database, table string) string
	GetTableDDL(database, table string) (string, error)
}

// DatabaseTransaction 数据库事务接口
type DatabaseTransaction interface {
	Commit() error
	Rollback() error
	ExecuteQuery(ctx context.Context, query string, args ...interface{}) (*models.QueryResult, error)
	ExecuteNonQuery(ctx context.Context, query string, args ...interface{}) (int64, error)
	Exec(query string, args ...interface{}) (sql.Result, error)
}

// DatabaseManager 数据库管理器接口
type DatabaseManager interface {
	// 配置管理
	SaveConfig(config *models.DatabaseConfig) error
	GetConfig(id string) (*models.DatabaseConfig, error)
	GetAllConfigs() ([]*models.DatabaseConfig, error)
	DeleteConfig(id string) error
	UpdateConfig(config *models.DatabaseConfig) error
	SetDefaultConfig(id string) error
	GetDefaultConfig() (*models.DatabaseConfig, error)

	// 连接管理
	GetConnection(configID string) (DatabaseDriver, error)
	CreateConnection(config *models.DatabaseConfig) (DatabaseDriver, error)
	CloseConnection(configID string) error
	CloseAllConnections() error
	GetConnectionStatus(configID string) (*models.ConnectionStatus, error)
	TestConnection(config *models.DatabaseConfig) error

	// 数据库操作（通过配置ID）
	ListDatabases(configID string) ([]models.DatabaseInfo, error)
	ListTables(configID, database string) ([]models.TableInfo, error)
	GetTableColumns(configID, database, table string) ([]models.ColumnInfo, error)
	GetTableIndexes(configID, database, table string) ([]models.IndexInfo, error)
	ExecuteQuery(configID, query string, args ...interface{}) (*models.QueryResult, error)
	ExecuteNonQuery(configID, query string, args ...interface{}) (int64, error)
}

// DriverFactory 驱动工厂接口
type DriverFactory interface {
	CreateDriver(dbType models.DatabaseType) (DatabaseDriver, error)
	SupportedTypes() []models.DatabaseType
}

// ConfigStorage 配置存储接口
type ConfigStorage interface {
	Save(config *models.DatabaseConfig) error
	Get(id string) (*models.DatabaseConfig, error)
	GetAll() ([]*models.DatabaseConfig, error)
	Delete(id string) error
	Update(config *models.DatabaseConfig) error
	SetDefault(id string) error
	GetDefault() (*models.DatabaseConfig, error)
}

// PasswordManager 密码管理接口
type PasswordManager interface {
	Encrypt(password string) (string, error)
	Decrypt(encryptedPassword string) (string, error)
}

// QueryBuilder 查询构建器接口
type QueryBuilder interface {
	// 数据库信息查询
	BuildListDatabasesQuery(dbType models.DatabaseType) string
	BuildListTablesQuery(dbType models.DatabaseType, database string) string
	BuildTableColumnsQuery(dbType models.DatabaseType, database, table string) string
	BuildTableIndexesQuery(dbType models.DatabaseType, database, table string) string
	BuildTableStatsQuery(dbType models.DatabaseType, database, table string) string

	// 通用查询
	BuildLimitQuery(dbType models.DatabaseType, query string, limit, offset int) string
	BuildCountQuery(query string) string
}

// ConnectionPool 连接池接口
type ConnectionPool interface {
	Get(configID string) (DatabaseDriver, error)
	Put(configID string, driver DatabaseDriver) error
	Remove(configID string) error
	Clear() error
	Size() int
	GetStats() map[string]interface{}
}

// DatabaseMetadata 数据库元数据接口
type DatabaseMetadata interface {
	GetDatabaseInfo(ctx context.Context, database string) (*models.DatabaseInfo, error)
	GetTableInfo(ctx context.Context, database, table string) (*models.TableInfo, error)
	GetColumnInfo(ctx context.Context, database, table string) ([]models.ColumnInfo, error)
	GetIndexInfo(ctx context.Context, database, table string) ([]models.IndexInfo, error)
	GetForeignKeys(ctx context.Context, database, table string) ([]models.IndexInfo, error)
}

// SQLDialect SQL方言接口
type SQLDialect interface {
	QuoteIdentifier(identifier string) string
	QuoteString(str string) string
	GetDataTypeMapping() map[string]string
	GetLimitClause(limit, offset int) string
	GetCurrentTimeFunction() string
	GetAutoIncrementClause() string
}

// BaseDriver 基础驱动结构
type BaseDriver struct {
	Config    *models.DatabaseConfig
	DB        *sql.DB
	Connected bool
	Dialect   SQLDialect
}

// Common methods that can be shared across drivers
func (bd *BaseDriver) IsConnected() bool {
	return bd.Connected && bd.DB != nil
}

func (bd *BaseDriver) Ping() error {
	if bd.DB == nil {
		return ErrNotConnected
	}
	return bd.DB.Ping()
}

func (bd *BaseDriver) Disconnect() error {
	if bd.DB != nil {
		err := bd.DB.Close()
		bd.Connected = false
		bd.DB = nil
		return err
	}
	return nil
}

func (bd *BaseDriver) GetRawConnection() interface{} {
	return bd.DB
}
